<template>
  <div class="container">
    <div style="margin-bottom: 10px;margin-left: 10px;">
      <el-button type="success" round @click="websocketConnect" size="mini">连接</el-button>
      <el-button type="danger" round @click="closeWebSocket" size="mini" style="margin-left: 20px;">断开</el-button>
    </div>
    <div id="terminal-container"></div>
  </div>
</template>

<script>
import 'xterm/css/xterm.css'
import { Terminal } from 'xterm'

import { getAppId, getSign, nowTime, getWebsocketURL, getToken } from '@/utils/auth'
import { getUUID32 } from '@/utils/index'

export default {
  name: 'Xterm',
  props: {
    containerId: {
      type: String,
      required: true
    },
    serverId: {
      type: String,
      required: true
    },
    url: {
      type: String,
      required: true
    }
  },
  data() {
    return {
      term: '',
      webSocket_connect: null
    }
  },
  mounted() {
    this.initXterm();
  },
  methods: {
    // 打开websocket连接
    websocketConnect() {
      // 判断当前浏览器是否支持WebSocket
      if ('WebSocket' in window) {
        var param = {}
        param['app_id'] = getAppId()
        param['connect_key'] = getUUID32()
        param['timestamp'] = nowTime()
        var api = getWebsocketURL() + this.url +
          '?app_id=' + param.app_id +
          '&connect_key=' + param.connect_key +
          '&container_id=' + this.containerId +
          '&container_name=' + this.containerName +
          '&timestamp=' + param.timestamp +
          '&token=' + getToken() +
          '&server_id=' + this.serverId +
          '&sign=' + getSign(param)
        this.webSocket_connect = new WebSocket(api)
      } else {
        this.term.write('当前浏览器不支持websocket')
        return
      }
      // 监听窗口关闭事件，当窗口关闭时，主动去关闭websocket连接，防止连接还没断开就关闭窗口，server端会抛异常。
      window.onbeforeunload = this.closeWebSocket

      // 连接发生错误的回调方法
      this.webSocket_connect.onerror = this.websocketConnectOnerror

      // 连接成功建立的回调方法
      this.webSocket_connect.onopen = this.websocketConnectOnopen

      // 接收到消息的回调方法
      this.webSocket_connect.onmessage = this.websocketOnmessage

      // 连接关闭的回调方法
      this.webSocket_connect.onclose = this.websocketOnclose
    },
    //websocket关闭
    websocketOnclose(e) {
      this.websocket_connect = null
      this.term.writeln('\r\n')
      this.term.writeln('onclose')

    },
    // websocket收到消息
    websocketOnmessage(e) {
      let res = JSON.parse(e.data)
      console.log(res)
      this.term.write(res.data.data)
    },
    //websocket连接打开
    websocketConnectOnopen(e) {
      //在页面上显示连接中...
      this.term.clear()
      this.term.writeln('\r\n')
      this.term.writeln('Connecting...')
    },
    //websocket连接错误
    websocketConnectOnerror(e) {
      this.term.writeln('\r\n')
      this.term.writeln('onerror')
      this.term.writeln(e)
      // console.log(e)
      this.websocket_connect = null
    },
    // 关闭WebSocket连接
    closeWebSocket() {
      this.term.writeln('\r\n')
      if (!this.webSocket_connect) {
        this.term.writeln('not connect')
        return
      }
      this.webSocket_connect.close()
      this.term.writeln('closed')
      this.websocket_connect = null
    },
    // 发送消息
    send(message) {
      if (!this.webSocket_connect) {
        this.term.writeln('not connect')
        return
      }
      this.webSocket_connect.send(message)
    },
    initXterm(){
      let _this = this
      let terminalContainer = document.getElementById('terminal-container')
      let term = new Terminal({
        cols: 78,
        rows: 30,
        cursorBlink: true, // 光标闪烁
        cursorStyle: 'underline', // 光标样式  null | 'block' | 'underline' | 'bar'
        scrollback: 600, //回滚
        tabStopWidth: 8, //制表宽度
        screenKeys: true,
      })
      this.term = term
      // this.websocketConnect()

      term.open(terminalContainer)
      term.onData(function(key) {
        let order = {
          cmd: 'on_message',
          data: {
            data:key,
            cmd:'server_cmd'
          }
        }
        _this.send(JSON.stringify(order))
      })
      term.focus();
    }
  }
}
</script>
<style lang="scss" scoped>

  .el-button--mini.is-round {
      padding: 5px 10px;
  }

</style>
